package helpers

import (
	"encoding/json"
	"errors"
	"fmt"
	"reflect"
	"time"
)

func Empty(value interface{}) bool {

	if value == nil {
		return false
	}

	v := reflect.ValueOf(value)
	switch v.Kind() {
	case reflect.String, reflect.Array:
		return v.Len() == 0
	case reflect.Map, reflect.Slice:
		return v.Len() == 0 || v.IsNil()
	case reflect.Bool:
		return v.Bool()
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return v.Int() == 0
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return v.Uint() == 0
	case reflect.Float32, reflect.Float64:
		return v.Float() == 0
	case reflect.Interface, reflect.Ptr:
		return v.IsNil()
	}

	return reflect.DeepEqual(value, reflect.Zero(v.Type()).Interface())
}

// MicrosecondsStr 将 time.Duration 类型（nano seconds 为单位）
// 输出为小数点后 3 位的 ms （microsecond 毫秒，千分之一秒）
func MicrosecondsStr(elapsed time.Duration) string {
	return fmt.Sprintf("%.3fms", float64(elapsed.Nanoseconds())/1e6)
}

func Test() {
	fmt.Print("123")
}

func EchoType(v interface{}) {
	typeof := reflect.TypeOf(v)
	fmt.Println("type", typeof.Name(), typeof.Kind())
}

func EchoStr(v interface{}) {
	fmt.Println("3333", v)
}

func structAssign(binding interface{}, value interface{}) {
	bVal := reflect.ValueOf(binding).Elem() //获取reflect.Type类型
	vVal := reflect.ValueOf(value).Elem()   //获取reflect.Type类型
	vTypeOfT := vVal.Type()
	for i := 0; i < vVal.NumField(); i++ {
		// 在要修改的结构体中查询有数据结构体中相同属性的字段，有则修改其值
		name := vTypeOfT.Field(i).Name
		if ok := bVal.FieldByName(name).IsValid(); ok {
			bVal.FieldByName(name).Set(reflect.ValueOf(vVal.Field(i).Interface()))
		}
	}
}

func Copy(from, to interface{}) error {
	b, err := json.Marshal(from)

	if err != nil {
		return errors.New("marshal from data err" + err.Error())
	}

	err = json.Unmarshal(b, to)
	if err != nil {
		return errors.New("unmarshal to data err" + err.Error())
	}

	return nil
}

func S_map_to_array(m map[string]string) interface{} {

	var map_len int = len(m)
	var slice1 = make([]map[string]string, map_len)

	var i1 = 0
	for i, v := range m {
		ma := make(map[string]string)
		ma["key"] = i
		ma["value"] = v
		slice1[i1] = ma
		i1++
	}

	return slice1
}

func S_struct_to_map(m interface{}) map[string]interface{} {
	typeof := reflect.TypeOf(m)
	var mapstr map[string]interface{}
	//fmt.Println("type",typeof.Name(),typeof.Kind())
	if typeof.Kind() == reflect.Struct {
		str, _ := json.Marshal(m)
		json.Unmarshal([]byte(str), &mapstr)
		return mapstr
	}
	return nil
}

func S_mapStruct_to_mapMap(m []interface{}) interface{} {
	//typeof  := reflect.TypeOf(m)
	//fmt.Println("type",typeof.Name(),typeof.Kind())
	//if typeof.Kind() == reflect.Slice {
	//
	//	mapstr := cast.ToStringSlice(m)
	//
	//	fmt.Println("map",mapstr)
	//}

	for item, value := range m {
		fmt.Print("item", item)
		fmt.Print("value", value)
		//mapstr[item] = S_struct_to_map(value)
	}
	//return  mapstr
	return true

}
